package blackberry.util.field;

import java.util.Vector;

import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.LabelField;
import util.DjStringEditor;
import blackberry.util.DjColorData;

/**
 * @사용법
 *  평소에는 getPrefferedHeight(field)를 사용한다. 하지만 이것은 1줄의 높이만을 반환하기때문에
 *  전체의 height 가 필요할 경우에는 getHeight()를 사용한다. 
 */
public class DjLabelField extends LabelField {

	private static final int DEFAULT_WIDTH = Display.getWidth();
	private static final int NOT_SET = -1;
	private int _width;
	
	private int _fontColor = Color.BLACK;
	private int _fontGlobalAlpha = 255;
	
	public static DjLabelField createSimpleLabel(String label){
		return new DjLabelField(label, null, null, 0);
	}
	
	public static DjLabelField createSimpleLabel(String label, int style){
		return new DjLabelField(label, null, null, style);
	}
	
	public static DjLabelField createNewFontLabel(String label, Font font){
		return new DjLabelField(label, null, font, 0);
	}
	
	public static DjLabelField createNewFontLabel(String label, Font font, int style){
		return new DjLabelField(label, null, font, style);
	}
	
	public static DjLabelField createColorLabel(String label, DjColorData colorData){
		return new DjLabelField(label, colorData, null, 0);
	}
	
	public static DjLabelField createColorLabel(String label, DjColorData colorData, int style){
		return new DjLabelField(label, colorData, null, style);
	}
	
	public static DjLabelField createColorNewFontLabel(String label, DjColorData colorData, Font font){
		return new DjLabelField(label, colorData, font, 0);
	}
	
	public static DjLabelField createColorNewFontLabel(String label, DjColorData colorData, Font font, int style){
		return new DjLabelField(label, colorData, font, style);
	}
	
	private DjLabelField(String label, DjColorData colorData, Font font, long style) {
		super(label, style);
		if (colorData != null) {
			_fontColor = colorData.getColor();
			_fontGlobalAlpha = colorData.getGlobalAlpha();
		}
		if (font != null) {
			setFont(font);
		}
		setFitLabel();
	}
	
	/**
	 * _width 설정 메소드들
	 */
	public void setFitLabel(){
		_width = NOT_SET;
		relayout();
	}

	public void setTrimLabel(int width) {
		_width = width;
		relayout();
	}

	private void relayout() {
		layout(getPreferredWidth(), 0);//Extent 값을 바로 사용 할수 있게함
	}
	
	/**
	 * @재정의_이유 
	 *  오른쪽 여백을 없에고 원하는 위치에서줄바꿈을 하기위해
	 *  
	 * @getPreferredWidth의_역할 
	 * 	return 값이 '문자열의 width'가 되어 줄바꿈의 기준이된다.(layout()에서 이것을 호출하는듯)
	 * 
	 * @super.getPreferredWidth의_문제점 
	 *  '\n'을 무시한 길다란 1줄의 width 값을 반환한다. 이것은 더러워 보일 수 있다.
	 *  
	 * @해결책
	 *  여백이 남지 않는 적절한 return 값을 반환해야 한다.
	 *   
	 * @return1 가장 긴 문자열의('\n'기준) width 값을 반환한다.
	 * @return2 _width 값이 입력되었다면 그 값을 반환한다.    
	 */
	public int getPreferredWidth() {
		if (_width == NOT_SET) { 
			int maxStringWidth = getMaxStringWidth();
			if (maxStringWidth <= DEFAULT_WIDTH) 
				return maxStringWidth;
			else
				return DEFAULT_WIDTH;
		} else {
			return _width;
		}
	}
	
	/**
	 * '\n' 을 기준으로 문자열 분리시킨 후에 그중 가장 큰 advance 값을 반환하도록 했다.
	 */
	private int getMaxStringWidth() {
		int[] lineFeedIndexes = getLineFeedIndexes();
		String maxString = "";
		for (int i = 0; i < lineFeedIndexes.length - 1/*2개씩 짝으로 비교하므로*/; i++) {
			String challengerString = null;
			if (i == 0) {//가장 처음 문자열 조각은 앞에 '\n' 을 포함하지 않으므로 무처리
				challengerString = getText().substring(lineFeedIndexes[i]/**/, lineFeedIndexes[i + 1]);
			} else {//2번째 문자열 부터는 앞에 '\n'을 포함하므로 앞쪽 index 에 (+1) 처리를 해서 지움
				challengerString = getText().substring(lineFeedIndexes[i] + 1/**/, lineFeedIndexes[i + 1]);
			}
			if (getAdvance(challengerString) > getAdvance(maxString))
				maxString = challengerString;
		}
		return getAdvance(maxString);
	}

	private int getAdvance(String str) {
		return getFont().getAdvance(str);
	}
	
	/**
	 * @return (맨앞(0) | '\n'... | 맨뒤)의 index정보를 담고있는 배열을 반환한다.
	 */
	private int[] getLineFeedIndexes() {
		Vector lineFeedIndexesVec = DjStringEditor.getCharIndexVec('\n', getText(), true);
		int[] lineFeedIndexes = new int[lineFeedIndexesVec.size() + 2];//문장의 맨앞, 맨끝 추가
		
		lineFeedIndexes[0] = 0;//맨앞
		for (int i = 0; i < lineFeedIndexesVec.size(); i++) {
			lineFeedIndexes[i + 1] = ((Integer) lineFeedIndexesVec.elementAt(i)).intValue();
		}
		lineFeedIndexes[lineFeedIndexes.length - 1] = getText().length();//맨끝
		return lineFeedIndexes;
	}

	
	/**
	 * color, globalAlpha 적용  
	 */
	protected void paint(Graphics g) {
		g.setGlobalAlpha(_fontGlobalAlpha);
		g.setColor(_fontColor);
		super.paint(g);
	}
}